;(function ($) {
    var isTouchPad = (/hp-tablet/gi).test(navigator.appVersion);
    var hasTouch = 'ontouchstart' in window && !isTouchPad;
    var touchStart = hasTouch ? 'touchstart' : 'mousedown';
    var touchMove = hasTouch ? 'touchmove' : 'mousemove';
    var touchEnd = hasTouch ? 'touchend' : 'mouseup';
    var doc = typeof document !== 'undefined' ? document : {};

    $.fn.slide = function (config) {
        var defaults = {
            type: "slide",
            effect: "left", // 效果，支持 left、leftLoop、leftMarquee、topMarquee
            delayTime: 800, // 效果持续时间
            defaultIndex: 0, // 默认的当前位置索引。0是第一个； defaultIndex:1时，相当于从第2个开始执行

            scroll: 1, //滚动元素个数
            vis: 1, //可视元素个数
            easing: "swing",

            slideEl: 'swip-slide',
            isPagination: false,//是否显示分页
            pagination: 'swip-pagination',//分页默认样式class名称
            isPaginationDefault: true,//是否默认分页样式
            paginationSlide: null,//分页效果函数

            autoPlay: false, //是否自动播放
            autoPlayStop: true, //手动滑动后是否停止自动播放
            interTime: 3000, //自动运行间隔
            slideStart: null,//每次切换效果开始时执行函数
            slideEnd: null,//每次切换效果结束时执行函数

            defaultPlay: true,//默认是否执行效果
            opp: false,//默认反方向运动
        };

        var el,
            opts = $.extend(defaults, config);
        this.each(function () {
            el = new Slide(this, opts);
        });
        return opts.api ? el : this;
    }

    function Slide(el, opts) {
        this._clearIntervalAll();

        var self = this;
        self.opts = opts;
        self.inter = null;// autoPlay的setInterval
        self.timeout = null; // leftLoop的setTimeout
        self.endTimeout = null;  //translate的setTimeout
        self.interTime = parseInt(opts.interTime);

        self.wrapperEl = el;
        self.$wrapperEl = $(el);
        self.containerEl = self.$wrapperEl.parent();
        self.slideEl = self.$wrapperEl.children();
        self.slideElSize = self.slideEl.length;
        //self.slideW = self.containerEl.width();
        self.tempSize = self.slideElSize;
        self.paginationSize = self.slideElSize;

        self.index = parseInt(self.opts.defaultIndex);
        self.startX = 0;
        self.startY = 0;
        self.distX = 0;
        self.distY = 0;

        self.scroll = parseInt(self.opts.scroll);
        self.vis = isNaN(self.opts.vis) ? 1 : parseInt(self.opts.vis);
        self.cloneNum = self.slideElSize >= self.vis ? (self.slideElSize % self.scroll != 0 ? self.slideElSize % self.scroll : self.scroll) : 0;
        self.isMarq = self.opts.effect == "leftMarquee" || self.opts.effect == "topMarquee" ? true : false;

        self._ind = parseInt(self.opts.defaultIndex);

        self.slideH = 0;
        self.slideW = 0;
        self.selfW = 0;
        self.selfH = 0;

        //处理分页
        if (self.opts.isPagination) {
            self._paginationInit();
        }

        //当内容个数少于可视个数，不执行效果。
        if (self.slideElSize >= self.vis) {
            //取最大值
            self.slideEl.each(function (index) {
                $(this).attr('data-swiper-slide-index', index);
                if ($(this).width() > self.selfW) {
                    self.selfW = $(this).width();
                    self.slideW = $(this).outerWidth(true);
                }
                if ($(this).height() > self.selfH) {
                    self.selfH = $(this).height();
                    self.slideH = $(this).outerHeight(true);
                }
            });

            switch (self.opts.effect) {
                case "left":
                    self.$wrapperEl.wrap('<div class="temp-wrapper" style="overflow:hidden; position:relative; width:' + self.vis * self.slideW + 'px"></div>').css({
                        "width": self.slideElSize * self.slideW,
                        // "left": -(self.index * self.scroll) * self.slideW,
                        "left": "0",
                        "position": "relative",
                        "overflow": "hidden",
                        "padding": "0",
                        "margin": "0"
                    }).children().css({"float": "left", "width": self.selfW});
                    break;
                case "leftLoop":
                case "leftMarquee":
                    cloneEle();
                    self.$wrapperEl.wrap('<div class="temp-wrapper" style="overflow:hidden; position:relative; width:' + self.vis * self.slideW + 'px"></div>').css({
                        "width": (self.slideElSize + self.vis + self.cloneNum) * self.slideW,
                        "position": "relative",
                        "overflow": "hidden",
                        "padding": "0",
                        "margin": "0",
                        // "left": -(self.cloneNum + self.index * self.scroll) * self.slideW
                        "left": "0",
                    }).children().css({"float": "left", "width": self.selfW});
                    break;
            }


            //添加“触摸开始”事件监听
            //self.$wrapperEl.on(touchStart, tStart);

            self.wrapperEl.addEventListener(touchStart, tStart, false);

            //兼容部分ios在滑动时e.preventDefault()无效问题
            document.addEventListener('touchmove', function (e) {
                //console.log(e.comesFromScrollable);
                if (e.comesFromScrollable) {
                    e.preventDefault();
                }
            }, {passive: false});
        }

        self._doPlay('init');

        //自动播放
        if (opts.autoPlay) {
            if (self.isMarq) {
                self.opp ? self.index-- : self.index++;
                setMarInter();
                //if(mouseOverStop) conBox.hover(pauseStateFun,playStateFun);
            } else {
                setInter();
                //if(mouseOverStop) slider.hover( pauseStateFun,playStateFun );
            }
        } else {
            if (self.isMarq) {
                self.opp ? self.index-- : self.index++;
            }
            //playState.addClass("pauseState");
        }

        //自动播放函数
        function setInter(time) {
            self.inter = setInterval(function () {
                self.opp ? self.index-- : self.index++;
                self._doPlay();
            }, !!time ? time : self.interTime);
        }

        //自动播放函数 leftMarquee
        function setMarInter(time) {
            self.inter = setInterval(self._doPlay(), !!time ? time : self.interTime);
        }

        //针对leftLoop、topLoop的滚动个数
        function scrollNum(ind) {
            var _tempCs = ind * self.scroll;
            if (ind == self.paginationSize) {
                _tempCs = self.slideElSize;
            } else if (ind == -1 && self.slideElSize % self.scroll != 0) {
                _tempCs = -self.slideElSize % self.scroll;
            }
            return _tempCs;
        }

        //针对leftLoop、topLoop克隆元素
        function cloneEle() {
            var _chr = self.slideEl;
            //克隆最前面的元素插入最后
            for (var i = 0; i < self.vis; i++) {
                _chr.eq(i).clone().addClass("clone").appendTo(self.$wrapperEl);
            }
            //克隆最后面的元素插入最前
            for (var i = 0; i < self.cloneNum; i++) {
                _chr.eq(self.slideElSize - i - 1).clone().addClass("clone").prependTo(self.$wrapperEl);
            }
        }

        /*
        tStart，tMove，tEnd方法不写在prototype的原因是：这3个方法是需要绑定的，ele.on(touchStart, tStart)，里面的this指针发生变化。
        如果写在prototype里面，将不能通过this.distX获取Slide的属性，这个时候this指向的是ele。
        */
        function tStart(e) {
            console.log('tStart');
            clearTimeout(self.timeout);
            clearTimeout(self.endTimeout);
            // conBox.addEventListener(touchStart, tStart ,false)
            // 原生绑定事件和jquery绑定事件e不一样
            if (e.originalEvent) e = e.originalEvent;
            scrollY = undefined;
            self.distX = 0;
            var point = hasTouch ? e.touches[0] : e;
            self.startX = point.pageX;
            self.startY = point.pageY;
            // self.$wrapperEl.on(touchMove, tMove);
            // self.$wrapperEl.on(touchEnd, tEnd);

            self.wrapperEl.addEventListener(touchMove, tMove, {passive: false});
            self.wrapperEl.addEventListener(touchEnd, tEnd, false);
        }

        function tMove(e) {
            console.log('tMove');
            if (e.originalEvent) e = e.originalEvent;
            if (hasTouch) {
                if (e.touches.length > 1 || e.scale && e.scale !== 1) return;
            }
            //多点或缩放
            var point = hasTouch ? e.touches[0] : e;
            self.distX = point.pageX - self.startX;
            self.distY = point.pageY - self.startY;
            if (typeof scrollY === 'undefined') {
                scrollY = (scrollY || Math.abs(self.distX) < Math.abs(self.distY));
            }
            if (!scrollY) {
                e.comesFromScrollable = true;
                e.preventDefault();
                if (self.opts.autoPlay) {
                    clearInterval(self.inter);
                }

                // switch (self.opts.effect) {
                //     case "left":
                //         self.$wrapperEl.wrap('<div class="tempWrap" style="overflow:hidden; position:relative; width:' + self.vis * self.slideW + 'px"></div>').css({
                //             "width": self.slideElSize * self.slideW,
                //             "left": -(self.index * self.scroll) * self.slideW,
                //             "position": "relative",
                //             "overflow": "hidden",
                //             "padding": "0",
                //             "margin": "0"
                //         }).children().css({"float": "left", "width": self.selfW});
                //         break;
                //     case "leftLoop":
                //     case "leftMarquee":
                //         cloneEle();
                //         self.$wrapperEl.wrap('<div class="tempWrap" style="overflow:hidden; position:relative; width:' + self.vis * self.slideW + 'px"></div>').css({
                //             "width": (self.slideElSize + self.vis + self.cloneNum) * self.slideW,
                //             "position": "relative",
                //             "overflow": "hidden",
                //             "padding": "0",
                //             "margin": "0",
                //             "left": -(self.cloneNum + self.index * self.scroll) * self.slideW
                //         }).children().css({"float": "left", "width": self.selfW});
                //         break;
                // }

                switch (self.opts.effect) {
                    case "left":
                        if ((self.index === 0 && self.distX > 0) || (self.index >= self.slideElSize - 1 && self.distX < 0)) {
                            self.distX = self.distX * 0.4;
                        }
                        self._translate(-self.index * self.slideW + self.distX, 0);
                        break;
                    case "leftLoop":
                        self._translate(-(self.index + 1) * self.slideW + self.distX, 0);
                        break;
                }
            } else {
                e.comesFromScrollable = false;
            }
        }

        function tEnd(e) {
            if (e.originalEvent) e = e.originalEvent;
            if (self.distX === 0) return;
            e.preventDefault();
            if (!scrollY) {
                if (Math.abs(self.distX) > self.slideW / 10) {
                    self.distX > 0 ? self.index-- : self.index++;
                }
                self._doPlay();
                if (self.opts.autoPlay && !self.opts.autoPlayStop) {
                    self.inter = setInterval(function () {
                        self.index++;
                        self._doPlay();
                    }, self.interTime);
                }
            }
            //self.$wrapperEl.off(touchMove, tMove);
            //self.$wrapperEl.off(touchEnd, tEnd);

            self.wrapperEl.removeEventListener(touchMove, tMove, {passive: false});
            self.wrapperEl.removeEventListener(touchEnd, tEnd, false);
        }
    }

    //原型方法
    Slide.prototype = {
        _paginationInit: function () {
            if (this.opts.isPagination) {
                if (this.opts.isPaginationDefault) {
                    var html = "<ol class='" + this.opts.pagination + "'>";
                    for (var i = 0; i < this.paginationSize; i++) {
                        if (i === parseInt(this.opts.defaultIndex)) {
                            html += "<li class='act'>" + (i + 1) + "</li>";
                        } else {
                            html += "<li>" + (i + 1) + "</li>";
                        }
                    }
                    html += "</ol>";
                    this.$wrapperEl.parent().append(html);
                }
            }
        },
        _paginationGo: function (param) {
            var self = this;
            if (this.opts.isPagination) {
                if (this.opts.isPaginationDefault) {
                    this.containerEl.find("." + this.opts.pagination).children().each(function (i) {
                        var _this = $(this);
                        if (i === parseInt(self.index)) {
                            if (!_this.hasClass('act')) {
                                _this.addClass('act');
                            }
                        } else {
                            if (_this.hasClass('act')) {
                                _this.removeClass('act');
                            }
                        }
                    });
                } else {
                    if ($.isFunction(this.opts.paginationSlide)) {
                        this.opts.paginationSlide.call(self, param);
                    }
                }
            }
        },
        _doPlay: function (idx) {
            var self = this;
            var isInit = false;
            if (typeof idx === 'undefined') {
                idx = this.index;
            } else if (idx == 'init') {
                isInit = true;
                idx = this.opts.defaultIndex;
            }
            var oldIndex = this.index;
            this.index = idx;

            // 当前页状态不触发效果
            //if( defaultPlay && oldIndex==index && !init && !isMarq ) return;

            //处理页码
            if (self.isMarq) {
                if (self.index >= 1) {
                    self.index = 1;
                } else if (self.index <= 0) {
                    self.index = 0;
                }
            } else {
                self._ind = self.index;
                // if (self.index >= self.paginationSize) {
                //     self.index = 0;
                // } else if (self.index < 0) {
                //     self.index = self.paginationSize - 1;
                // }
            }

            if ($.isFunction(this.opts.slideStart)) {
                this.opts.slideStart.apply(self, null);
            }

            switch (this.opts.effect) {
                case "left":
                    // self.$wrapperEl.stop(true, false).animate({"left": -self.index * self.scroll * self.slideW}, self.opts.delayTime, self.opts.easing, function () {
                    //     self.doEndFun();
                    // });
                    // break;

                if (idx > this.slideElSize - 1) {
                    this.index = this.slideElSize - 1;
                    clearInterval(self.inter);
                } else if (idx < 0) {
                    this.index = 0;
                }
                this._paginationGo(isInit ? 'init' : undefined);
                this._translate((-this.index * this.slideW), isInit ? 0 : this.opts.delayTime);
                if ((oldIndex >= this.slideElSize || oldIndex < 0) && !isInit) return;
                break;
                case "leftLoop":
                    this._translate(-(idx + 1) * this.slideW, isInit ? 0 : this.opts.delayTime);
                    if (idx < 0) {
                        self.timeout = setTimeout(function () {
                            self._translate(-self.slideElSize * self.slideW, 0);
                        }, this.opts.delayTime);
                        this.index = this.slideElSize - 1;
                    } else if (this.index > this.slideElSize - 1) {
                        self.timeout = setTimeout(function () {
                            self._translate(-self.slideW, 0);
                        }, this.opts.delayTime);
                        this.index = 0;
                    }
                    this._paginationGo(isInit ? 'init' : undefined);
                    oldIndex = this.index;
                    break;
            }

            if ($.isFunction(this.opts.slideEnd)) {
                var slideEnd = this.opts.slideEnd;
                self.endTimeout = window.setTimeout(function () {
                    slideEnd.apply(self, null);
                }, this.opts.delayTime);
            }
        },
        // _doPlay: function (idx) {
        //     var self = this;
        //     var isInit = false;
        //     if (typeof idx === 'undefined') {
        //         idx = this.index;
        //     } else if (idx == 'init') {
        //         isInit = true;
        //         idx = this.opts.defaultIndex;
        //     }
        //     var oldIndex = this.index;
        //     this.index = idx;
        //     switch (this.opts.effect) {
        //         case "left":
        //             if (idx > this.slideElSize - 1) {
        //                 this.index = this.slideElSize - 1;
        //                 clearInterval(self.inter);
        //             } else if (idx < 0) {
        //                 this.index = 0;
        //             }
        //             this._paginationGo(isInit ? 'init' : undefined);
        //             this._translate((-this.index * this.slideW), isInit ? 0 : this.opts.delayTime);
        //             if ((oldIndex >= this.slideElSize || oldIndex < 0) && !isInit) return;
        //             break;
        //         case "leftLoop":
        //             this._translate(-(idx + 1) * this.slideW, isInit ? 0 : this.opts.delayTime);
        //             if (idx < 0) {
        //                 self.timeout = setTimeout(function () {
        //                     self._translate(-self.slideElSize * self.slideW, 0);
        //                 }, this.opts.delayTime);
        //                 this.index = this.slideElSize - 1;
        //             } else if (this.index > this.slideElSize - 1) {
        //                 self.timeout = setTimeout(function () {
        //                     self._translate(-self.slideW, 0);
        //                 }, this.opts.delayTime);
        //                 this.index = 0;
        //             }
        //             this._paginationGo(isInit ? 'init' : undefined);
        //             oldIndex = this.index;
        //             break;
        //     }
        //     if ($.isFunction(this.opts.slideStart)) {
        //         this.opts.slideStart.apply(self, null);
        //     }
        //     if ($.isFunction(this.opts.slideEnd)) {
        //         var slideEnd = this.opts.slideEnd;
        //         self.endTimeout = window.setTimeout(function () {
        //             slideEnd.apply(self, null);
        //         }, this.opts.delayTime);
        //     }
        // },
        _translate: function (dist, speed, ele) {
            if (!!ele) {
                ele = ele.style;
            } else {
                ele = this.$wrapperEl[0].style;
            }
            ele.webkitTransitionDuration = ele.MozTransitionDuration = ele.msTransitionDuration = ele.OTransitionDuration = ele.transitionDuration = speed + 'ms';
            ele.webkitTransform = 'translate3d(' + dist + 'px,0,0)';
            //ele.webkitTransform = 'translate(' + dist + 'px,0)' + 'translateZ(0)';
            ele.msTransform = ele.MozTransform = ele.OTransform = 'translate3d(' + dist + 'px,0,0)';
            //ele.msTransform = ele.MozTransform = ele.OTransform = 'translateX(' + dist + 'px)';
        },
        _clearIntervalAll:function (){
            for (var i = 1; i < 2000; i++){
                window.clearInterval(i);
            }
        }
    };
})($);